<?php

/**
 * weixin api类
 */
class weixinModel
{


    public function __construct(& $base)
    {
        $this->base = $base;
        $this->db = & $this->base->db;
        $this->redis = & $this->base->redis;
    }

    static public $component_appid = 'wxdb4c8bb1e0408148';   // 服务开发方的appid
    static public $component_appsecret = '0c79e1fa963cd80cc0be99b20a18faeb';  // 服务开发方的app secret
    static public $component_appKey = 'tZqekGazVgap8AJ4EhhoKI2kpx5hqzDiT1io3J8tUC6';  // 服务开发方的app secret
    static public $appid = 'wx6e9f935be224ef2e';  // 公众号的appid
    // static public $appid = 'wx6e9f935be224ef2e';  // appid

    /**
     * 根据code 获取授权信息
     * @return array
     */
    public function getuthorInfo($code)
    {
        $authorInfo = array();
        
        $url = 'https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s&component_access_token=%s';

        $component_access_token = $this->getComponentAcsToken();

        $url = sprintf($url, self::$appid, $code, self::$component_appid, $component_access_token);
        $rel = common::getContents($url, '', 10, 'GET');

        if(common::is_json($rel))
        {
            $authorInfo = json_decode($rel, TRUE);
        }
        
        return $authorInfo;
    }
    /**
     * 获取服务开发方的access_token
     * @return array
     */
    public function getComponentAcsToken()
    {
        $redisKey = REDIS_PREFIX.'Wx';

        $component_access_token = $this->redis->hget($redisKey, 'component_access_token');

        if(!$component_access_token)
        {
            $component_access_token = $this->updateComponentAcsToken();
        }
        
        return $component_access_token;
    }
    /**
     * 更新 服务开发方的access_token
     * @return str
     */
    public function updateComponentAcsToken()
    {
        $component_access_token = '';

        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';

        $params = array('component_appid' => self::$component_appid,
                        'component_appsecret' => self::$component_appsecret,
                        'component_verify_ticket' => $this->getVerifyTiket()
            );


        $rel = $this->curl($url, $this->json_encode($params));

        if(common::is_json($rel))
        {
            $relArr = json_decode($rel, TRUE);
            if(isset($relArr['component_access_token']))
            {
                $component_access_token = $relArr['component_access_token'];

                $this->redis->hset(REDIS_PREFIX.'Wx', 'component_access_token', $component_access_token);
            }
        }

        return $component_access_token;
    }
    /**
     * 获取授权用户信息
     * @return array
     */
    public function getUserInfo($access_token, $openid)
    {
        $userInfo = array();
        
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN';
        $url = sprintf($url, $access_token, $openid);

        $rel = common::getContents($url);

        if(common::is_json($rel))
        {
            $userInfo = json_decode($rel, TRUE);
        }
        
        return $userInfo;
    }
    /**
     * 获取component_verify_ticket  （微信后台推送的ticket，此ticket会定时推送）
     * @return string
     */
    public function getVerifyTiket()
    {
        return $this->redis->hget(REDIS_PREFIX.'Wx', 'verifyTiket');
    }
    /**
     * 获取并更新 component_verify_ticket  （微信后台推送的ticket，此ticket会定时推送）
     * @return string
     */
    public function updateVerifyTiket($encryptStr)
    {
        require FILE . 'lib/weixin.class.php';

        $pc = new Prpcrypt(self::$component_appKey);
        $xmlArr = $pc->decrypt($encryptStr, self::$component_appid);
        $postStr = $xmlArr[1];

        $rst = (array)simplexml_load_string($postStr, "SimpleXMLElement", LIBXML_NOCDATA);

        $ComponentVerifyTicket = $rst['ComponentVerifyTicket'];
        $this->redis->hset(REDIS_PREFIX.'Wx', 'verifyTiket', $ComponentVerifyTicket);

        return $ComponentVerifyTicket;
    }
    /**
     * 保存微信用户信息
     * @return string
     */
    public function setAuthorUserInfo($userInfo)
    {
        if(isset($userInfo['openid']) && isset($userInfo['unionid']) && isset($userInfo['access_token']))
        {
            $insertData = array('openid' => $userInfo['openid'],
                                'unionid' => $userInfo['unionid'],
                                'access_token' => $userInfo['access_token'],
                                'nickname' => isset($userInfo['nickname']) ? $userInfo['nickname'] : '',
                                'sex' => isset($userInfo['sex']) ? $userInfo['sex'] : '',
                                'headimgurl' => isset($userInfo['headimgurl']) ? $userInfo['headimgurl'] : '',
                                'privilege' => isset($userInfo['privilege']) ? $userInfo['privilege'] : '',
                                'province' => isset($userInfo['province']) ? $userInfo['province'] : '',
                                'city' => isset($userInfo['city']) ? $userInfo['city'] : '',
                                'country' => isset($userInfo['country']) ? $userInfo['country'] : '',
                                'addtime' => time()
                );

            $this->db->insertRowTable('r_wxweb', $insertData);
        }

        return ;
    }
    /**
     * 对openid 进行简单加密
     * @return str
     */
    public function encryptOpenId($openid)
    {
        $prefix = 'LetItGo';

        $openid = base64_encode($prefix. $openid);
        $openid = urlencode($openid);

        return $openid;
    }
    /**
     * 获取微信用户信息
     * @return array
     */
    public function getwxUserInfo($openid)
    {
        $userInfo = $this->db->getRowTable('r_wxweb', array(), "openid='{$openid}'");

        empty($userInfo) && $userInfo = array();
        return $userInfo;
    }
    /**
     * 获取微信用户信息
     * @return array
     */
    private static function json_encode($arr)
    {
        $parts = array ();
        $is_list = false;
        //Find out if the given array is a numerical array
        $keys = array_keys ( $arr );
        $max_length = count ( $arr ) - 1;
        if (($keys [0] === 0) && ($keys [$max_length] === $max_length ))  //See if the first key is 0 and last key is length - 1
        {
            $is_list = true;
            for($i = 0; $i < count ( $keys ); $i ++)  //See if each key correspondes to its position
            {
                if ($i != $keys [$i]) //A key fails at position check.
                { 
                    $is_list = false; //It is an associative array.
                    break;
                }
            }
        }
        foreach ( $arr as $key => $value )
        {
            if (is_array ( $value ))
            { //Custom handling for arrays
                if ($is_list)
                        $parts [] = self::json_encode ( $value ); /* :RECURSION: */
                else
                        $parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */
            }
            else
            {
                $str = '';
                if (! $is_list)
                        $str = '"' . $key . '":';
                //Custom handling for multiple data types
                if (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)
                        $str .= $value; //Numbers
                elseif ($value === false)
                    $str .= 'false'; //The booleans
                elseif ($value === true)
                    $str .= 'true';
                else
                    $str .= '"' . addslashes ( $value ) . '"'; //All other things
                // :TODO: Is there any more datatype we should be in the lookout for? (Object?)
                $parts [] = $str;
            }
        }
        $json = implode ( ',', $parts );
        if ($is_list)
                return '[' . $json . ']'; //Return numerical JSON

        return '{' . $json . '}'; //Return associative JSON
    }
    private function curl($url,$param,$post_file=false)
    {
        $oCurl = curl_init();
        if(stripos($url,"https://")!==FALSE)
        {
                curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        if (is_string($param) || $post_file)
        {
                $strPOST = $param;
        }
        else
        {
            $aPOST = array();
            foreach($param as $key=>$val)
            {
                $aPOST[] = $key."=".urlencode($val);
            }
            $strPOST =  join("&", $aPOST);
        }

        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt($oCurl, CURLOPT_POST,true);
        curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        if(intval($aStatus["http_code"])==200){
                return $sContent;
        }else{
                return false;
        }
    }

}
?>